{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "from keras.layers import Input, Dense, LSTM\n",
    "from keras.models import Model\n",
    "from keras.layers import *\n",
    "from keras.models import *\n",
    "from keras.optimizers import Adam\n",
    "from keras.callbacks import EarlyStopping"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "from sklearn.preprocessing import MinMaxScaler\n",
    "import time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_csv(\"data/沪深300小时级别数据.csv\",header=0,index_col=None,sep='\\s+',parse_dates=[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>time</th>\n",
       "      <th>open</th>\n",
       "      <th>close</th>\n",
       "      <th>high</th>\n",
       "      <th>low</th>\n",
       "      <th>volume</th>\n",
       "      <th>money</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2012-01-04 10:30:00</td>\n",
       "      <td>2361.50</td>\n",
       "      <td>2348.51</td>\n",
       "      <td>2365.92</td>\n",
       "      <td>2346.60</td>\n",
       "      <td>1263715000</td>\n",
       "      <td>12097650000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2012-01-04 11:30:00</td>\n",
       "      <td>2348.83</td>\n",
       "      <td>2332.52</td>\n",
       "      <td>2350.21</td>\n",
       "      <td>2331.04</td>\n",
       "      <td>635382000</td>\n",
       "      <td>6084670000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2012-01-04 14:00:00</td>\n",
       "      <td>2332.40</td>\n",
       "      <td>2326.73</td>\n",
       "      <td>2334.76</td>\n",
       "      <td>2323.85</td>\n",
       "      <td>640358000</td>\n",
       "      <td>5843940000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2012-01-04 15:00:00</td>\n",
       "      <td>2327.24</td>\n",
       "      <td>2298.75</td>\n",
       "      <td>2327.24</td>\n",
       "      <td>2298.37</td>\n",
       "      <td>883373800</td>\n",
       "      <td>8406050000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2012-01-05 10:30:00</td>\n",
       "      <td>2290.78</td>\n",
       "      <td>2290.86</td>\n",
       "      <td>2308.68</td>\n",
       "      <td>2282.33</td>\n",
       "      <td>1197403500</td>\n",
       "      <td>10499450880</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>2012-01-05 11:30:00</td>\n",
       "      <td>2290.87</td>\n",
       "      <td>2306.45</td>\n",
       "      <td>2316.58</td>\n",
       "      <td>2284.62</td>\n",
       "      <td>1132892900</td>\n",
       "      <td>9694943232</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>2012-01-05 14:00:00</td>\n",
       "      <td>2306.37</td>\n",
       "      <td>2296.03</td>\n",
       "      <td>2308.16</td>\n",
       "      <td>2294.37</td>\n",
       "      <td>665050000</td>\n",
       "      <td>5726093312</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>2012-01-05 15:00:00</td>\n",
       "      <td>2296.52</td>\n",
       "      <td>2276.39</td>\n",
       "      <td>2296.60</td>\n",
       "      <td>2272.42</td>\n",
       "      <td>1295105600</td>\n",
       "      <td>11593711616</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                 time     open    close     high      low      volume  \\\n",
       "0 2012-01-04 10:30:00  2361.50  2348.51  2365.92  2346.60  1263715000   \n",
       "1 2012-01-04 11:30:00  2348.83  2332.52  2350.21  2331.04   635382000   \n",
       "2 2012-01-04 14:00:00  2332.40  2326.73  2334.76  2323.85   640358000   \n",
       "3 2012-01-04 15:00:00  2327.24  2298.75  2327.24  2298.37   883373800   \n",
       "4 2012-01-05 10:30:00  2290.78  2290.86  2308.68  2282.33  1197403500   \n",
       "5 2012-01-05 11:30:00  2290.87  2306.45  2316.58  2284.62  1132892900   \n",
       "6 2012-01-05 14:00:00  2306.37  2296.03  2308.16  2294.37   665050000   \n",
       "7 2012-01-05 15:00:00  2296.52  2276.39  2296.60  2272.42  1295105600   \n",
       "\n",
       "         money  \n",
       "0  12097650000  \n",
       "1   6084670000  \n",
       "2   5843940000  \n",
       "3   8406050000  \n",
       "4  10499450880  \n",
       "5   9694943232  \n",
       "6   5726093312  \n",
       "7  11593711616  "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head(8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(8096, 7)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_feature = df[['close','open','high', 'low', 'volume', 'money']].astype('float')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "sample_num = df.shape[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_num = int(df.shape[0] * 0.8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_num = df.shape[0] - train_num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(8096, 6476, 1620)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sample_num,train_num,test_num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(6476, 6) (1620, 6)\n"
     ]
    }
   ],
   "source": [
    "data_train = df_feature.iloc[:train_num, :]\n",
    "data_test = df_feature.iloc[train_num:, :]\n",
    "print(data_train.shape, data_test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "MinMaxScaler(copy=True, feature_range=(0, 1))"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "scaler = MinMaxScaler(feature_range=(0, 1))\n",
    "scaler.fit(data_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_train = scaler.transform(data_train)\n",
    "data_test = scaler.transform(data_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(6476,) (1620,)\n"
     ]
    }
   ],
   "source": [
    "data_train_y = np.array(df_feature.iloc[:train_num, 0])\n",
    "data_test_y = np.array(df_feature.iloc[train_num:, 0])\n",
    "print(data_train_y.shape, data_test_y.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "PAST_TIME_STEPS = 40\n",
    "NEXT_TIME_STEPS = 12"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train = np.array([data_train[i : i + PAST_TIME_STEPS, :] for i in range(0,data_train.shape[0] - (NEXT_TIME_STEPS+ PAST_TIME_STEPS),4)])\n",
    "X_test = np.array([data_test[i : i + PAST_TIME_STEPS, :] for i in range(0,data_test.shape[0] - (NEXT_TIME_STEPS+ PAST_TIME_STEPS),4)])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train_class = np.array([1 if data_train_y[i + PAST_TIME_STEPS + NEXT_TIME_STEPS-1] - data_train_y[i + PAST_TIME_STEPS-1] > 0 else 0 for i in range(0,data_train.shape[0] - (NEXT_TIME_STEPS+ PAST_TIME_STEPS),4)])\n",
    "y_test_class = np.array([1 if data_test_y[i + PAST_TIME_STEPS + NEXT_TIME_STEPS-1]- data_test_y[i + PAST_TIME_STEPS-1] > 0 else 0 for i in range(0,data_test.shape[0] - (NEXT_TIME_STEPS+ PAST_TIME_STEPS),4)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1606, 40, 6) (1606,) (392, 40, 6) (392,)\n"
     ]
    }
   ],
   "source": [
    "print(X_train.shape, y_train_class.shape, X_test.shape,y_test_class.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "INPUT_DIM = data_train.shape[1]\n",
    "output_dim = 1\n",
    "batch_size = 32 #每轮训练模型时，样本的数量\n",
    "epochs = 100 #训练60轮次\n",
    "hidden_size = 128\n",
    "lstm_units = 64"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(?, 1, 64)\n"
     ]
    }
   ],
   "source": [
    "inputs = Input(shape=(PAST_TIME_STEPS, INPUT_DIM))\n",
    "#drop1 = Dropout(0.3)(inputs)\n",
    "x = Conv1D(filters = 64, kernel_size = 1, activation = 'relu')(inputs)  #, padding = 'same'\n",
    "#x = Conv1D(filters=128, kernel_size=5, activation='relu')(output1)#embedded_sequences\n",
    "x = MaxPooling1D(pool_size = PAST_TIME_STEPS)(x)\n",
    "x = Dropout(0.1)(x)\n",
    "print(x.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(?, 128)\n"
     ]
    }
   ],
   "source": [
    "lstm_out = Bidirectional(LSTM(lstm_units, activation='relu'), name='bilstm')(x)\n",
    "#lstm_out = LSTM(lstm_units,activation='relu')(x)\n",
    "print(lstm_out.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ATTENTION PART STARTS HERE\n",
    "attention_probs = Dense(128, activation='sigmoid', name='attention_vec')(lstm_out)\n",
    "#attention_mul=layers.merge([stm_out,attention_probs], output_shape],mode='concat',concat_axis=1))\n",
    "attention_mul =Multiply()([lstm_out, attention_probs])\n",
    "#attention_mul = merge([lstm_out, attention_probs],output_shape=32, name='attention_mul', mode='mul')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "__________________________________________________________________________________________________\n",
      "Layer (type)                    Output Shape         Param #     Connected to                     \n",
      "==================================================================================================\n",
      "input_1 (InputLayer)            (None, 40, 6)        0                                            \n",
      "__________________________________________________________________________________________________\n",
      "conv1d_1 (Conv1D)               (None, 40, 64)       448         input_1[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling1d_1 (MaxPooling1D)  (None, 1, 64)        0           conv1d_1[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "dropout_1 (Dropout)             (None, 1, 64)        0           max_pooling1d_1[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "bilstm (Bidirectional)          (None, 128)          66048       dropout_1[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "attention_vec (Dense)           (None, 128)          16512       bilstm[0][0]                     \n",
      "__________________________________________________________________________________________________\n",
      "multiply_1 (Multiply)           (None, 128)          0           bilstm[0][0]                     \n",
      "                                                                 attention_vec[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_1 (Dense)                 (None, 1)            129         multiply_1[0][0]                 \n",
      "==================================================================================================\n",
      "Total params: 83,137\n",
      "Trainable params: 83,137\n",
      "Non-trainable params: 0\n",
      "__________________________________________________________________________________________________\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "output_class = Dense(1, activation='sigmoid')(attention_mul)\n",
    "#output = Dense(10, activation='sigmoid')(drop2)\n",
    "\n",
    "model_class = Model(inputs=inputs, outputs=output_class)\n",
    "print(model_class.summary())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 1606 samples, validate on 392 samples\n",
      "Epoch 1/100\n",
      "1606/1606 [==============================] - 2s 1ms/step - loss: 0.6934 - acc: 0.4857 - val_loss: 0.6924 - val_acc: 0.5281\n",
      "Epoch 2/100\n",
      "1606/1606 [==============================] - 0s 128us/step - loss: 0.6923 - acc: 0.5255 - val_loss: 0.6922 - val_acc: 0.5281\n",
      "Epoch 3/100\n",
      "1606/1606 [==============================] - 0s 127us/step - loss: 0.6920 - acc: 0.5255 - val_loss: 0.6923 - val_acc: 0.5281\n",
      "Epoch 4/100\n",
      "1606/1606 [==============================] - 0s 132us/step - loss: 0.6918 - acc: 0.5255 - val_loss: 0.6925 - val_acc: 0.5281\n",
      "Epoch 5/100\n",
      "1606/1606 [==============================] - 0s 138us/step - loss: 0.6917 - acc: 0.5255 - val_loss: 0.6926 - val_acc: 0.5281\n",
      "Epoch 6/100\n",
      "1606/1606 [==============================] - 0s 133us/step - loss: 0.6916 - acc: 0.5255 - val_loss: 0.6925 - val_acc: 0.5281\n",
      "Epoch 7/100\n",
      "1606/1606 [==============================] - 0s 130us/step - loss: 0.6915 - acc: 0.5255 - val_loss: 0.6925 - val_acc: 0.5281\n",
      "Epoch 8/100\n",
      "1606/1606 [==============================] - 0s 134us/step - loss: 0.6916 - acc: 0.5255 - val_loss: 0.6925 - val_acc: 0.5281\n",
      "Epoch 9/100\n",
      "1606/1606 [==============================] - 0s 137us/step - loss: 0.6913 - acc: 0.5255 - val_loss: 0.6924 - val_acc: 0.5281\n",
      "Epoch 10/100\n",
      "1606/1606 [==============================] - 0s 132us/step - loss: 0.6913 - acc: 0.5255 - val_loss: 0.6924 - val_acc: 0.5281\n",
      "Epoch 11/100\n",
      "1606/1606 [==============================] - 0s 125us/step - loss: 0.6911 - acc: 0.5255 - val_loss: 0.6924 - val_acc: 0.5281\n",
      "Epoch 12/100\n",
      "1606/1606 [==============================] - 0s 130us/step - loss: 0.6911 - acc: 0.5255 - val_loss: 0.6924 - val_acc: 0.5281\n",
      "Epoch 00012: early stopping\n"
     ]
    }
   ],
   "source": [
    "model_class.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])\n",
    "# simple early stopping\n",
    "es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=10)\n",
    "# fit model\n",
    "history_class = model_class.fit(X_train, y_train_class,validation_data=(X_test, y_test_class), epochs=epochs, batch_size=batch_size, shuffle=False, callbacks=[es])\n",
    "y_pred_class = model_class.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1606/1606 [==============================] - 0s 44us/step\n",
      "392/392 [==============================] - 0s 46us/step\n",
      "Train: 0.526, Test: 0.528\n"
     ]
    }
   ],
   "source": [
    "# evaluate the model\n",
    "_, train_acc = model_class.evaluate(X_train, y_train_class, verbose=1)\n",
    "_, test_acc = model_class.evaluate(X_test, y_test_class, verbose=1)\n",
    "print('Train: %.3f, Test: %.3f' % (train_acc, test_acc))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plot training history\n",
    "plt.plot(history_class.history['loss'], label='train')\n",
    "plt.plot(history_class.history['val_loss'], label='test')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:py35]",
   "language": "python",
   "name": "conda-env-py35-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
